-
Notifications
You must be signed in to change notification settings - Fork 1.1k
GH-3993: Fix async race condition in TcpOutGateway #3995
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Fixes spring-projects#3993 When `TcpOutboundGateway` is in an `async` mode and `CCF` is configured not for `singleUse` an `Semaphore` around an obtained `TcpConnection` is involved. If we fail on `TcpConnection.send()`, resources are not clean up, including the mentioned `Semaphore`: in async mode this happens only when we receive a reply. * Catch an exception on the `TcpConnection.send()` and perform `cleanUp()` in async mode. * Add `cleanUp()` into a scheduled task from the `TcpOutboundGateway.AsyncReply` when no reply arrives in time. * Optimize `TcpOutboundGateway.AsyncReply` behavior to cancel no-reply scheduled task when reply arrives into a `CompletableFuture` **Cherry-pick to `5.5.x`**
this.noResponseFuture = | ||
getTaskScheduler() | ||
.schedule(() -> { | ||
cleanUp(this.haveSemaphore, this.connection, this.connection.getConnectionId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's a new race here; we could end up releasing the semaphore twice because onMessage
calls cleanup before completing the future.
Perhaps check if pendingReplies
was actually removed in cleanup before releasing the semaphore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See some fixed I have pushed.
only if `future.completeExceptionally()` is `true`
Needs back port due to |
Forget that; since it's internal, we can use |
* GH-3993: Fix async race condition in TcpOutGateway Fixes #3993 When `TcpOutboundGateway` is in an `async` mode and `CCF` is configured not for `singleUse` an `Semaphore` around an obtained `TcpConnection` is involved. If we fail on `TcpConnection.send()`, resources are not clean up, including the mentioned `Semaphore`: in async mode this happens only when we receive a reply. * Catch an exception on the `TcpConnection.send()` and perform `cleanUp()` in async mode. * Add `cleanUp()` into a scheduled task from the `TcpOutboundGateway.AsyncReply` when no reply arrives in time. * Optimize `TcpOutboundGateway.AsyncReply` behavior to cancel no-reply scheduled task when reply arrives into a `CompletableFuture` **Cherry-pick to `5.5.x`** * * Call `cleanUp()` from no response scheduled task only if `future.completeExceptionally()` is `true`
...and cherry-picked as 1aef041 after resolving conflicts. |
That's OK, Gary.
So, your catch is good. I'll provide the fix in subsequent commit... |
Oops - compile error too. |
An adaptation to |
Fixes #3993
When
TcpOutboundGateway
is in anasync
mode andCCF
is configured not forsingleUse
anSemaphore
around an obtainedTcpConnection
is involved. If we fail onTcpConnection.send()
, resources are not clean up, including the mentionedSemaphore
: in async mode this happens only when we receive a reply.TcpConnection.send()
and performcleanUp()
in async mode.cleanUp()
into a scheduled task from theTcpOutboundGateway.AsyncReply
when no reply arrives in time.TcpOutboundGateway.AsyncReply
behavior to cancel no-reply scheduled task when reply arrives into aCompletableFuture
Cherry-pick to
5.5.x